package org.vectrics.common.dom;


import org.apache.log4j.*;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.Attr;




public class DomUtils {
	private transient static Logger log = Logger.getLogger(DomUtils.class);
	
	public static String elementToXml(Node node) {
		return(elementToXml(node, 0, false));
	}
	
	public static String elementToXml(Node node, boolean pretty) {
		return(elementToXml(node, 0, pretty));
	}
	
	//walk the DOM tree and print as u go
	public static String elementToXml(Node node, int level, boolean pretty)
	{
		log.debug("elementToXML() called");
		StringBuffer buffer = new StringBuffer();
		String tabStr = "";
		if (pretty) {
			if (level > 0) {
				for (int i = 0; i < level; i++)
					tabStr += '\t';
			}
		}
		
		int type = node.getNodeType();
		switch(type){
			case Node.DOCUMENT_NODE:
			{
				buffer.append("<?xml version=\"1.0\" encoding=\""+
						"UTF-8" + "\"?>\r\n");  
				break;                  
			}//end of document
			case Node.ELEMENT_NODE:
			{
				if (pretty) {
					buffer.append("\r\n");
					buffer.append(tabStr);
				}
				buffer.append('<' + node.getNodeName() );
				
				NamedNodeMap nnm = node.getAttributes();
				
				if(nnm != null )
				{
					int len = nnm.getLength() ;
					Attr attr;
					for ( int i = 0; i < len; i++ )
					{
						attr = (Attr)nnm.item(i);
						buffer.append(' ' 
								+ attr.getNodeName()
								+ "=\""
								+ attr.getNodeValue()
								+  '"' );
					}
				}
				buffer.append('>');
				
				break;
				
			}//end of element
			case Node.ENTITY_REFERENCE_NODE:
			{
				
				buffer.append('&' + node.getNodeName() + ';' );
				break;
				
			}//end of entity
			case Node.CDATA_SECTION_NODE:
			{
				buffer.append( "<![CDATA[" 
						+ node.getNodeValue()
						+ "]]>" );
				break;       
				
			}
			case Node.TEXT_NODE:
			{
				buffer.append(node.getNodeValue());
				break;
			}
			case Node.PROCESSING_INSTRUCTION_NODE:
			{
				buffer.append("<?" 
						+ node.getNodeName() ) ;
				String data = node.getNodeValue();
				if ( data != null && data.length() > 0 ) {
					buffer.append(' ');
					buffer.append(data);
				}
				buffer.append("?>\r\n");
				break;
	
			}
		}//end of switch
		
		
		//recurse
		for(Node child = node.getFirstChild(); child != null; child = child.getNextSibling())
		{
			buffer.append(elementToXml(child, level + 1, pretty));
		}
		
		//without this the ending tags will miss
		if ( type == Node.ELEMENT_NODE )
		{
			buffer.append("</" + node.getNodeName() + ">");
		}
		return(buffer.toString());
	}	

	
}
